import datetime
import logging
from dataclasses import dataclass

from src.application.order.uow import OrderUoW
from src.application.user.exceptions import NotEnoughBalance
from src.domain.order.value_objects import OrderId
from src.infrastructure.date_helpers import get_date_time

logger = logging.getLogger(__name__)


@dataclass(frozen=True)
class UpdateOrderExpiring:
    order_id: int
    expiring_on: datetime.datetime


class UpdateOrderExpiringHandler:
    """Продление заказа"""

    def __init__(
        self,
        *,
        uow: OrderUoW,
    ) -> None:
        self._uow = uow

    async def __call__(self, command: UpdateOrderExpiring) -> None:
        cur_date = get_date_time()
        order_id = OrderId(command.order_id)
        order = await self._uow.order_repo.acquire_order_by_id(order_id)
        user = await self._uow.user_repo.acquire_user_by_id(order.buyer_id)

        if user.balance < order.summ:
            raise NotEnoughBalance(user.tg_id.value)

        order.update_expiring(command.expiring_on, cur_date)
        user.decrease_balance(order.summ)

        try:
            await self._uow.order_repo.update_order(order)
            await self._uow.user_repo.update_user(user)
        except Exception as err:
            await self._uow.rollback()
            raise err

        await self._uow.commit()

        logger.info(f"Order №{command.order_id} has been extended to {command.expiring_on}")
